//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <winhack.h>
#include <elasys_server.h>
#include <stdlib.h>
#include <stdio.h>
#include "CDirStrEnumerator.h"

UInt32 CDirStrEnumerator::AddRef()
{
    LONG nRef = m_cRef.Increment();
    return (ULONG)nRef;
}

UInt32 CDirStrEnumerator::Release()
{
    LONG nRef = m_cRef.Decrement();

    if (0 == nRef) {
        delete this;
    }
    return nRef;
}

ECode CDirStrEnumerator::Aggregate(
    AggregateType type, PInterface pObj)
{
    return E_NOT_IMPLEMENTED;
}

ECode CDirStrEnumerator::GetDomain(
    IInterface **ppObj)
{
    return E_NOT_IMPLEMENTED;
}

PInterface CDirStrEnumerator::Probe(REIID riid)
{
    if (EIID_IInterface == riid) {
        return (IInterface *)(IWStringEnumerator *)this;
    }
    else if (EIID_IWStringEnumerator == riid) {
        return (IWStringEnumerator *)this;
    }
    else if (EIID_CLASS_INFO == riid) {
        return (IInterface *)&ECLSID_CKtfsDirStrEnumerator;
    }
    else if (EIID_INTERFACE_INFO == riid) {
        return (IInterface *)&EIID_IWStringEnumerator;
    }

    return NULL;
}

CDirStrEnumerator::CDirStrEnumerator()
{
}

CDirStrEnumerator::CDirStrEnumerator(
    wchar_t *wcsPathName)
{
    wchar_t *wcsTempPathName = (wchar_t *)malloc(sizeof(wchar_t)
                                                 * (wcslen(wcsPathName)+1));
    assert(wcsTempPathName);
    wcscpy(wcsTempPathName, wcsPathName);
    m_wstrPathName = wcsTempPathName;
    m_hFind = INVALID_HANDLE_VALUE;
    m_bMove = FALSE;
    m_bReset = TRUE;
}

CDirStrEnumerator::~CDirStrEnumerator()
{
    free(m_wstrPathName);
    FindClose(m_hFind);
}

ECode CDirStrEnumerator::Current(
    /* [out] */ WStringBuf * pPsa)
{
    if (m_bReset == TRUE
      || m_wcsFileName[0] == '\0') {
        return E_INVALID_OPERATION;
    }
    
    if (NULL == pPsa 
      || pPsa->IsNull()
      || pPsa->GetCapacity() < (Int32)wcslen(m_wcsFileName)) {
        return E_INVALID_ARGUMENT;
    }
    
    pPsa->Copy(m_wcsFileName);
    return NOERROR;
}

ECode CDirStrEnumerator::MoveNext(
    /* [out] */ Boolean* pSucceeded)
{
    if (pSucceeded == NULL) {
        return E_INVALID_OPERATION;
    }

    *pSucceeded = FALSE;
    m_bReset = FALSE;
    WIN32_FIND_DATAW FindFileData;
    if (!m_bMove) {
        m_hFind = FindFirstFileW(m_wstrPathName, &FindFileData);
        if (m_hFind == INVALID_HANDLE_VALUE) {
            return E_FILE_NOT_FOUND;
        }
        m_bMove = TRUE;
    }
    else {
        if (m_hFind == INVALID_HANDLE_VALUE ||
            !FindNextFileW(m_hFind, &FindFileData)) {
             m_wcsFileName[0] = '\0';
             return NOERROR;
        }
    }
    wcscpy(m_wcsFileName, FindFileData.cFileName);
    *pSucceeded = TRUE;
    return NOERROR;
}

ECode CDirStrEnumerator::Reset()
{
    m_bReset = TRUE;
    m_bMove = FALSE;
    FindClose(m_hFind);
    m_hFind = INVALID_HANDLE_VALUE;
    return NOERROR;
}
